#pragma once
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <iostream>
#include <cstring>
#include <unistd.h>
static const int gsock = -1;
static const int gport = -1;

class UdpServer
{
public:
    UdpServer(int port = gport)
        : _port(port), _sock(gsock)
    {
    }

    // 1.套接字
    //  Init的任务就是创建服务器套接字，并且绑定端口+ip
    void Init()
    {
        _sock = socket(AF_INET, SOCK_DGRAM, 0);
        if (_sock < 0)
        {
            std::cout << "创建套接字失败!" << std::endl;
            exit(-1);
        }
        std::cout << "创建套接字成功:" << _sock << std::endl;

        // 2.绑定端口
        struct sockaddr_in local;
        bzero(&local, sizeof(local));
        local.sin_family = AF_INET;
        local.sin_port = htons(_port);
        local.sin_addr.s_addr = INADDR_ANY; // 任意地址

        // 填充完毕了，写到内核里
        int n = ::bind(_sock, (struct sockaddr *)&local, sizeof(local));
        if (n!=0)
        {
            std::cout << "绑定失败!" << std::endl;
            exit(-2);
        }
        std::cout<<"绑定成功,端口号:"<<_port<<std::endl;
    }

    // 服务器启动
    void Start()
    {
        char buffer[1024];
        while (true)
        {
            // 存放client的信息
            struct sockaddr_in peer;
            socklen_t len = sizeof(peer);
            ssize_t n = recvfrom(_sock, buffer, sizeof(buffer) - 1, 0, (struct sockaddr *)&peer, &len);

            if (n > 0)
            {
                std::cout << "获取新连接" << std::endl;
                buffer[n] = 0;
                std::cout << "client say:" << buffer << std::endl;
                // 将消息发送回去
                const char *msg = "hello client!";
                int m = sendto(_sock, msg, strlen(msg), 0, (struct sockaddr *)&peer, len);
                if (m > 0)
                {
                    std::cout << "sned to client success!!" << std::endl;
                }
            }
        }
    }

    ~UdpServer()
    {
        close(_sock);
    }

private:
    int _port;
    int _sock;
};



